/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller;

import Assignment.BLO.BookBLO;
import Assignment.BLO.OrderBLO;
import Assignment.BLO.UserBLO;
import Assignment.DTO.BookDTO;
import Assignment.DTO.UserDTO;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import javazoom.upload.MultipartFormDataRequest;
import javazoom.upload.UploadBean;
import javazoom.upload.UploadException;
import javazoom.upload.UploadFile;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 *
 * @author Arturia
 */
public class Controller extends HttpServlet {

    boolean isAdmin = false;
    private boolean found = false;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            String action = "";
            MultipartFormDataRequest mRequest = null;
            if (MultipartFormDataRequest.isMultipartFormData(request)) {
                try {
                    mRequest = new MultipartFormDataRequest(request);
                } catch (UploadException ex) {
                    //ex.printStackTrace();
                    Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
                }
                action = mRequest.getParameter("Action");
                if (action.equals("EditBook") || action.equals("InsertBook")) {
                    String bookID = mRequest.getParameter("bookid");
                    String title = mRequest.getParameter("title");
                    String author = mRequest.getParameter("author");
                    String publisher = mRequest.getParameter("publisher");
                    String description = mRequest.getParameter("description");
                    String category = mRequest.getParameter("category");
                    String oldimg = "";


                    Calendar calendar = Calendar.getInstance();
                    Date dateModify = calendar.getTime();
                    float price = Float.parseFloat(mRequest.getParameter("price"));
                    int inventory = Integer.parseInt(mRequest.getParameter("inventory"));
                    boolean bestseller = mRequest.getParameter("bestseller") != null ? true : false;

                    BookDTO bookTmp = new BookDTO();
                    bookTmp.setBookID(bookID);
                    bookTmp.setTitle(title);
                    bookTmp.setAuthor(author);
                    bookTmp.setPublisher(publisher);
                    bookTmp.setDescription(description);
                    bookTmp.setCategory(category);
                    bookTmp.setDateModify(dateModify);
                    bookTmp.setPrice(price);
                    bookTmp.setInventory(inventory);
                    bookTmp.setBestseller(bestseller);

                    //image
                    //ServletContext context = this.getServletContext();
                    //String filePath = context.getInitParameter("file-upload");
                    String contentType = request.getContentType();
                    if ((contentType.indexOf("multipart/form-data") >= 0)) {
                        //System.out.println("1");
                        try {

                            Hashtable files = mRequest.getFiles();
                            //Create file name
                            UploadFile uFile = (UploadFile) files.get("image");
                            //String fileName = uFile.getFileName();
                            if (uFile.getFileName() == null) {
                                oldimg = mRequest.getParameter("oldlink");
                                bookTmp.setImageLink(oldimg);
                            } else {
                                uFile.setFileName(uFile.getFileName() + System.currentTimeMillis());

                                if (uFile != null) {
                                    UploadBean upBean = new UploadBean();
                                    String imagePath = getServletContext().getRealPath("/") + "covers";
                                    upBean.setFolderstore(imagePath);
                                    upBean.store(mRequest, "image");
                                    bookTmp.setImageLink(uFile.getFileName());
                                }
                            }

                            BookBLO bBLO = new BookBLO();
                            if (action.equals("EditBook")) {
                                bBLO.updateBook(bookTmp);
                            } else {
                                bBLO.insertBook(bookTmp);
                            }
                            RequestDispatcher rd = request.getRequestDispatcher("admin.jsp");
                            rd.forward(request, response);
                        } catch (UploadException e) {
                            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);
                        }
                    }
                }

            } else {
                action = request.getParameter("Action");
                if (action.equals("Register")) {
                    String username = request.getParameter("username");
                    String password = request.getParameter("password");
                    String realname = request.getParameter("realname");
                    String email = request.getParameter("email");
                    String address = request.getParameter("address");
                    String phone = request.getParameter("phone");
                    String city = request.getParameter("city");
                    String dob = request.getParameter("birth");
                    Date dtdob = new Date();
                    DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
                    try {
                        dtdob = (Date) df.parse(dob);
                    } catch (ParseException e) {
                        Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);
                    }
                    //boolean isAdmin = false;
                    UserDTO user = new UserDTO(username, password, email, realname, dtdob, address, city, phone, false);
                    boolean isFalse = false;
                    UserBLO ublo = new UserBLO();
                    isFalse = ublo.registerUser(user);
                    if (isFalse == false) {
                        request.setAttribute("USERNAMEEXITS", "true");
                        RequestDispatcher rd = request.getRequestDispatcher("register.jsp");
                        rd.forward(request, response);
                    } else {
                        request.setAttribute("USERNAMEEXITS", "false");
                        ublo.getAllUsers();
                        RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
                        rd.forward(request, response);
                    }
                } else if (action.equals("Login")) {
                    String username = request.getParameter("username");
                    String password = request.getParameter("password");

                    String url = "";
                    HttpSession session = request.getSession(true);
                    session.setMaxInactiveInterval(60 * 60); //session co gia tri trong 30 phut
                    String result = null;
                    result = checkLogin(username, password);
                    if (!result.equals("")) {
                        //if username has already been in xml file
                        session.setAttribute("USER", username);
                        session.setAttribute("LOGINFAIL", "false");
                        if (result.equals("true")) {
                            url = "admin.jsp";
                            session.setAttribute("ISADMIN", "true");
                        } else if (result.equals("false")) {
                            url = "index.jsp";
                            session.setAttribute("ISADMIN", "false");
                        }
                    } else {
                        //user do not exits
                        session.setAttribute("LOGINFAIL", "true");
                        url = "login.jsp";
                    }
                    RequestDispatcher rd = request.getRequestDispatcher(url);
                    rd.forward(request, response);
                } else if (action.equals("Search")) {
                    String search = request.getParameter("searchText");
                    HttpSession session = request.getSession(true);
                    session.setAttribute("SEARCHSTRING", search);
                    //request.setAttribute("SEARCHSTRING", search);
                    //request.setAttribute("CATEGORY", "false");
                    String category = request.getParameter("Category");
                    if (category == null) {
                        request.setAttribute("CATEGORY", "false");
                    } else {
                        request.setAttribute("CATEGORY", "true");
                    }
                    RequestDispatcher rd = request.getRequestDispatcher("search.jsp");
                    rd.forward(request, response);
                } else if (action.equals("Logout")) {
                    HttpSession session = request.getSession();
//                if (session.getAttribute("USER") != null) {
//                    session.setAttribute("USER", null);
//                }
                    session.invalidate();
                    RequestDispatcher rd = request.getRequestDispatcher("index.jsp");
                    rd.forward(request, response);
                } else if (action.equals("AddCart")) {
                    HttpSession session = request.getSession(true);
                    String user = (String) session.getAttribute("USER");
                    if (user == null) {
                        RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
                        rd.forward(request, response);
                    } else {
                        CartList list = (CartList) session.getAttribute("cart");
                        if (list == null) {
                            list = new CartList();
                        }
                        CartBean cart = new CartBean();
                        cart.setBookID(request.getParameter("bookID"));
                        cart.setQuantity(Integer.parseInt(request.getParameter("quantity")));
                        list.addBook(cart);
                        session.setAttribute("cart", list);

                        RequestDispatcher rd = request.getRequestDispatcher("bookdetail.jsp");
                        rd.forward(request, response);
                    }
                } else if (action.equals("RemoveCart")) {
                    HttpSession session = request.getSession(true);
                    CartList list = (CartList) session.getAttribute("cart");
                    if (list != null) {
                        String[] bookIDs = request.getParameterValues("cBox");
                        if (bookIDs != null) {
                            for (int i = 0; i
                                    < bookIDs.length; i++) {
                                try {
                                    list.remove(bookIDs[i]);
                                } catch (Exception e) {
                                    Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);
                                }
                            }
                            session.setAttribute("cart", list);
                            if (list.getList().isEmpty()) {
                                RequestDispatcher rd = request.getRequestDispatcher("index.jsp");
                                rd.forward(request, response);
                            } else {
                                RequestDispatcher rd = request.getRequestDispatcher("viewcart.jsp");
                                rd.forward(request, response);
                            }
                        } else {
                            RequestDispatcher rd = request.getRequestDispatcher("viewcart.jsp");
                            rd.forward(request, response);
                        }
                    }
                } else if (action.equals("CheckOut")) {
                    HttpSession session = request.getSession(true);
                    CartList cart = (CartList) session.getAttribute("cart");
                    String user = (String) session.getAttribute("USER");
                    float totalPrice = Float.parseFloat(request.getParameter("hidTotal"));
                    OrderBLO oBLO = new OrderBLO();
                    Calendar calendar = Calendar.getInstance();
                    Date deliveryDate = new Date();
                    deliveryDate = calendar.getTime();
                    // delivery within 7 days after order
                    deliveryDate = new Date(deliveryDate.getTime() + 7 * 24 * 60 * 60 * 1000);
                    if (!oBLO.checkout(user, deliveryDate, totalPrice, "", cart)) {
                        Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, "Check out failed");
                    }
                    session.removeAttribute("cart");
                    RequestDispatcher rd = request.getRequestDispatcher("index.jsp");
                    rd.forward(request, response);
                } else if (action.equals("AddMore")) {
                    //HttpSession session = request.getSession(true);
                    RequestDispatcher rd = request.getRequestDispatcher("index.jsp");
                    rd.forward(request, response);
                } else if (action.equals("Delete book")) {
                    String[] bookIDs = request.getParameterValues("cBox");
                    BookBLO bBLO = new BookBLO();
                    bBLO.deleteBooks(bookIDs);
                    RequestDispatcher rd = request.getRequestDispatcher("admin.jsp");
                    rd.forward(request, response);
                } else if (action.equals("Delete order")) {
                    String[] orderIDs = request.getParameterValues("cBox");
                    OrderBLO oBLO = new OrderBLO();
                    for (int i = 0; i
                            < orderIDs.length; i++) {
                        oBLO.deleteOrderByOrderID(orderIDs[i]);
                    }
                    RequestDispatcher rd = request.getRequestDispatcher("vieworder.jsp");
                    rd.forward(request, response);
                }
            }
        } catch (Exception e) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);
        } finally {
            out.close();
        }
    }

    private String checkLogin(String username, String password) {
        //XMLInputFactory xif = XMLInputFactory.newInstance();
        //String file = getServletContext().getRealPath("/") + "WEB-INF/accounts.xml";
        try {
            Properties prop = new Properties();
            //InputStream in = getServletContext().getResourceAsStream("/Properties/dbCon.properties");
            InputStream input = Controller.class.getResourceAsStream("/Properties/dbConnection.properties");
            prop.load(input);
            String path = prop.getProperty("userxml");
            File file = new File(path);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(file);
            XPathFactory xpf = XPathFactory.newInstance();
            XPath xpath = xpf.newXPath();
            String sql = "//User[normalize-space(username)= '" + username + "' and normalize-space(password) = '" + password + "']/isAdmin";
            //NodeList list = (NodeList) xpath.evaluate(sql, doc, XPathConstants.NODESET);
            String reString = (String) xpath.evaluate(sql, doc, XPathConstants.STRING);
            return reString;

            /*xif.setEventAllocator(new XMLEventAllocatorImpl());
            FileReader fileReader = new FileReader(file);
            XMLEventReader xer = xif.createXMLEventReader(fileReader);
            //boolean found1 = false;
            while (xer.hasNext()) {
            XMLEvent event = xer.nextEvent();
            if (event.isStartElement()) {
            StartElement start = event.asStartElement();
            if (start.getName().getLocalPart().equals("username")) {
            XMLEvent userEvent = xer.peek();
            Characters chars = userEvent.asCharacters();
            if (chars.getData().trim().equals(username)) {
            userEvent = xer.nextEvent();
            userEvent = xer.nextTag();
            userEvent = xer.nextTag();
            userEvent = xer.peek();
            chars = userEvent.asCharacters();
            if (chars.getData().trim().equals(password)) {
            // get isAdmin
            String strAdmin = "";
            do {
            XMLEvent isAdminEvent = xer.nextEvent();
            if (isAdminEvent.isStartElement()) {
            start = isAdminEvent.asStartElement();
            strAdmin = start.getName().getLocalPart();
            if (strAdmin.equals("isAdmin")) {
            isAdminEvent = xer.peek();
            chars = isAdminEvent.asCharacters();
            if (chars.getData().trim().equals("true")) {
            isAdmin = true;
            } else {
            isAdmin = false;
            }
            break;
            }
            }
            } while (!strAdmin.equals("isAdmin"));

            return true;
            //break;
            }
            }
            }
            }
            }
            } catch (XMLStreamException e) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);
            } catch (FileNotFoundException e) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);*/
        } catch (IOException e) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);
        } catch (ParserConfigurationException e) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);
        } catch (SAXException e) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);
        } catch (XPathExpressionException e) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, e);
        }




        return null;




    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);




    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);




    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";


    }// </editor-fold>
}
